package com.feiyuan.modules.sys.service.impl;

import com.feiyuan.modules.sys.vo.GeneratorMetaVO;
import com.feiyuan.modules.sys.vo.GeneratorRoutersVO;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.feiyuan.common.utils.PageUtils;
import com.feiyuan.common.utils.Query;

import com.feiyuan.modules.sys.mapper.MenuDao;
import com.feiyuan.modules.sys.entity.MenuEntity;
import com.feiyuan.modules.sys.service.MenuService;


@Service("menuService")
public class MenuServiceImpl extends ServiceImpl<MenuDao, MenuEntity> implements MenuService {

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<MenuEntity> page = this.page(
                new Query<MenuEntity>().getPage(params),
                new QueryWrapper<MenuEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public Object listMenus(Map<String, Object> params) {
        List<MenuEntity> menuList = this.list();
        // 查询所有的父级菜单
        List<MenuEntity> collect = menuList.stream().filter((menu) -> {
            return menu.getParentId() == 0;
        }).map((menu) -> {
            List<MenuEntity> children = this.getChildren(menu, menuList);
            if (children != null && children.size() > 0) {
                menu.setChildren(children);
            } else {
                menu.setChildren(null);
            }
            return menu;
        }).sorted((menu1, menu2) -> {
            if (menu1.getOrderNum() != null && menu2.getOrderNum() != null) {
                return menu1.getOrderNum() - menu2.getOrderNum();
            }
            return 0;
        }).collect(Collectors.toList());
        return collect;
    }

    @Override
    public Object selectParentId() {
        List<MenuEntity> menuList = baseMapper.selectList(new QueryWrapper<MenuEntity>().in("type", 0, 1));
        // 查询所有的父级菜单
        List<MenuEntity> collect = menuList.stream().filter((menu) -> {
            return menu.getParentId() == 0;
        }).map((menu) -> {
            List<MenuEntity> children = this.getChildren(menu, menuList);
            if (children != null && children.size() > 0) {
                menu.setChildren(children);
            } else {
                menu.setChildren(null);
            }
            return menu;
        }).sorted((menu1, menu2) -> {
            if (menu1.getOrderNum() != null && menu2.getOrderNum() != null) {
                return menu1.getOrderNum() - menu2.getOrderNum();
            }
            return 0;
        }).collect(Collectors.toList());
        return collect;
    }

    @Override
    public List<GeneratorRoutersVO> nav(String userId) {
        // 根据用户ID查询用户的权限
        List<MenuEntity> menus = baseMapper.selectMenus(userId);
//        List<MenuEntity> menus = baseMapper.selectList(new QueryWrapper<MenuEntity>().in("type", 0, 1));
        List<GeneratorRoutersVO> collect = menus.stream().filter((menu) -> {
            return menu.getParentId() == 0;
        }).map((menu) -> {
            List<GeneratorRoutersVO> grvs = getNavChildren(menu, menus);
            GeneratorRoutersVO grv = new GeneratorRoutersVO();
            grv.setPath(menu.getUrl());
            grv.setName(menu.getMenuKey());
            grv.setComponent("RouteView");
            GeneratorMetaVO meta = new GeneratorMetaVO();
            meta.setTitle(menu.getName());
            meta.setKeepAlive(true);
            meta.setIcon(menu.getIcon());
            grv.setMeta(meta);
            grv.setChildren(grvs);
            grv.setOrderNum(menu.getOrderNum());
            grv.setId(menu.getMenuId());
            grv.setParentId(menu.getParentId());
            grv.setKey(menu.getMenuKey());
            return grv;
        }).collect(Collectors.toList());
        return collect.stream().sorted((menu1, menu2) -> {
            if (menu1.getOrderNum() != null && menu2.getOrderNum() != null) {
                return menu1.getOrderNum() - menu2.getOrderNum();
            }
            return 0;
        }).collect(Collectors.toList());
    }

    private List<GeneratorRoutersVO> getNavChildren(MenuEntity root, List<MenuEntity> menus) {
        List<GeneratorRoutersVO> routeView = menus.stream().filter((menu) -> {
            return menu.getParentId() == root.getMenuId();
        }).map((menu) -> {
            List<GeneratorRoutersVO> grvs = getNavChildren(menu, menus);
            GeneratorRoutersVO grv = new GeneratorRoutersVO();
            grv.setPath(menu.getUrl());
            grv.setName(menu.getMenuKey());
            GeneratorMetaVO meta = new GeneratorMetaVO();
            meta.setTitle(menu.getName());
            meta.setIcon(menu.getIcon());
            if (menu.getType().intValue() == 0) {
                meta.setKeepAlive(true);
                grv.setComponent("RouteView");
            } else {
                grv.setComponent(menu.getUrl());
                List<String> permissions = new ArrayList<>();
                List<MenuEntity> menuEntities = baseMapper.selectList(new QueryWrapper<MenuEntity>().eq("parent_id", menu.getMenuId()));
                for (MenuEntity menuEntity : menuEntities) {
                    permissions.add(menuEntity.getPerms());
                }
                meta.setPermission(permissions);
                meta.setKeepAlive(true);
            }
            grv.setMeta(meta);
            grv.setChildren(grvs);
            grv.setOrderNum(menu.getOrderNum());
            grv.setId(menu.getMenuId());
            grv.setParentId(menu.getParentId());
            grv.setKey(menu.getMenuKey());
            return grv;
        }).collect(Collectors.toList());
        return routeView.stream().sorted((menu1, menu2) -> {
            if (menu1.getOrderNum() != null && menu2.getOrderNum() != null) {
                return menu1.getOrderNum() - menu2.getOrderNum();
            }
            return 0;
        }).collect(Collectors.toList());
    }

    private List<MenuEntity> getChildren(MenuEntity root, List<MenuEntity> menuList) {
        List<MenuEntity> collect = menuList.stream().filter((menu) -> {
            return menu.getParentId() == root.getMenuId();
        }).map((menu) -> {
            List<MenuEntity> children = this.getChildren(menu, menuList);
            if (children != null && children.size() > 0) {
                menu.setChildren(children);
            } else {
                menu.setChildren(null);
            }
            return menu;
        }).sorted((menu1, menu2) -> {
            if (menu1.getOrderNum() != null && menu2.getOrderNum() != null) {
                return menu1.getOrderNum() - menu2.getOrderNum();
            }
            return 0;
        }).collect(Collectors.toList());
        return collect;
    }

}